package com.bsfcs.rag.utils;

import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.codec.multipart.FilePart;
import reactor.core.publisher.Mono;

public class FilePartUtils {

    // 阈值，超过这个大小就用流式处理（单位：字节）
    private static final long MEMORY_THRESHOLD = 5 * 1024 * 1024; // 5 MB

    public static Mono<Resource> toResource(FilePart filePart) {
        if (filePart.headers().getContentLength() <= MEMORY_THRESHOLD) {
            // 小文件，收集所有数据并创建 ByteArrayResource
            return filePart.content()
                    .reduce(new byte[0], (bytes, dataBuffer) -> {
                        int readableBytes = dataBuffer.readableByteCount();
                        byte[] result = new byte[bytes.length + readableBytes];
                        System.arraycopy(bytes, 0, result, 0, bytes.length);
                        dataBuffer.read(result, bytes.length, readableBytes);
                        return result;
                    })
                    .map(bytes -> new ByteArrayResource(bytes) {
                        @Override
                        public String getFilename() {
                            return filePart.filename();
                        }
                    });
        } else {
            // 对于大文件，我们仍然收集所有内容到内存中（在实际项目中，可能需要使用临时文件）
            // 这里为了简化实现，仍然使用同样的方法
            return filePart.content()
                    .reduce(new byte[0], (bytes, dataBuffer) -> {
                        int readableBytes = dataBuffer.readableByteCount();
                        byte[] result = new byte[bytes.length + readableBytes];
                        System.arraycopy(bytes, 0, result, 0, bytes.length);
                        dataBuffer.read(result, bytes.length, readableBytes);
                        return result;
                    })
                    .map(bytes -> new ByteArrayResource(bytes) {
                        @Override
                        public String getFilename() {
                            return filePart.filename();
                        }
                    });
        }
    }
}
